package com.chixing.service.impl;

import com.chixing.entity.Car;
import com.chixing.mapper.CarMapper;
import com.chixing.service.RecommendService;
import org.apache.mahout.cf.taste.common.TasteException;
import org.apache.mahout.cf.taste.impl.neighborhood.NearestNUserNeighborhood;
import org.apache.mahout.cf.taste.impl.recommender.GenericItemBasedRecommender;
import org.apache.mahout.cf.taste.impl.recommender.GenericUserBasedRecommender;
import org.apache.mahout.cf.taste.impl.similarity.PearsonCorrelationSimilarity;
import org.apache.mahout.cf.taste.model.DataModel;
import org.apache.mahout.cf.taste.neighborhood.UserNeighborhood;
import org.apache.mahout.cf.taste.recommender.RecommendedItem;
import org.apache.mahout.cf.taste.recommender.Recommender;
import org.apache.mahout.cf.taste.similarity.ItemSimilarity;
import org.apache.mahout.cf.taste.similarity.UserSimilarity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class RecommendServiceImpl implements RecommendService {
   @Autowired
   private CarMapper carMapper;
   @Autowired
   private DataModel dataModel;

    @Override
    public List<Car> getRecommentProductByUser(Integer custId, Integer howMany) {
       List<Car> carList = new ArrayList<>();
        try {
            /*计算相似度，相似度的计算方式很多，采用基于皮尔逊相关性的相似度*/
            UserSimilarity similarity = new PearsonCorrelationSimilarity(dataModel);
            /*
                计算最近邻居，邻居有两种算法：基于固定数量的邻居和基于相似度的邻居
                这里采用基于固定数量的邻居
            */
            UserNeighborhood userNeighborhood = new NearestNUserNeighborhood(100,similarity,dataModel);
            /*构建推荐器，基于用户的协同过滤推荐*/
            Recommender recommender = new GenericUserBasedRecommender(dataModel,userNeighborhood,similarity);
            long startTime = System.currentTimeMillis();
            /*推荐商品*/
            List<RecommendedItem> recommendedItemList =  recommender.recommend(custId,howMany);
            List<Integer> carIds =  new ArrayList<>();
            for(RecommendedItem recommendedItem : recommendedItemList){
                System.out.println("recommendedItem:" + recommendedItem);
                carIds.add((int) recommendedItem.getItemID());
            }
            System.out.println("车辆Id集合为:" + carIds);
            /*根据商品id 查询商品*/
            if(carIds != null && carIds.size() >0){
                for(Integer carId:carIds){
                    Car car = carMapper.selectById(carId);
                    carList.add(car);
                }
            }else {
                carList = new ArrayList<>();
            }
            System.out.println("推荐数量是：" + carList.size() + ",耗时：" + (System.currentTimeMillis()-startTime));
        } catch (TasteException e) {
            e.printStackTrace();
        }
        return carList;
    }

    @Override
    public List<Car> getRecommentProductByProduct(Integer custId, Integer carId, Integer howMany) {
        List<Car> carList = new ArrayList<>();
        try {
            /*计算相似度，相似度的计算方式很多，采用基于皮尔逊相关性的相似度*/
            ItemSimilarity itemSimilarity = new PearsonCorrelationSimilarity(dataModel);
            /*构建推荐器，基于用户的协同过滤推荐*/
            GenericItemBasedRecommender recommender = new GenericItemBasedRecommender(dataModel,itemSimilarity);
            long startTime = System.currentTimeMillis();
            /*推荐商品*/
            List<RecommendedItem> recommendedItemList =  recommender.recommendedBecause(custId,carId,howMany);
            List<Integer> carIds =  new ArrayList<>();
            for(RecommendedItem recommendedItem : recommendedItemList){
                System.out.println("recommendedItem:" + recommendedItem);
                carIds.add((int) recommendedItem.getItemID());
            }
            System.out.println("车辆Id集合为:" + carIds);

            /*根据商品id 查询商品*/
            if(carIds != null && carIds.size() >0){
                for(Integer carsid:carIds){
                    Car car = carMapper.selectById(carsid);
                    carList.add(car);
                }
            }else {
                carList = new ArrayList<>();
            }
            System.out.println("推荐数量是：" + carList.size() + ",耗时：" + (System.currentTimeMillis()-startTime));
        } catch (TasteException e) {
            e.printStackTrace();
        }
        return carList;

    }
}
